﻿using System.Windows.Media;

namespace System.Windows.Controls
{

    /// <summary>
    /// Intended to place elements directly on ellipse track by providing them with angle and radius
    /// </summary>
    public class DirectRadialPanel : Panel
    {

        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.RegisterAttached(
            "Angle",
            typeof(Double),
            typeof(DirectRadialPanel),
            new PropertyMetadata(0.0, new PropertyChangedCallback(OnAnglePropertyChanged))
            );
        public static void SetAngle(UIElement element, Double value)
        {
            element.SetValue(AngleProperty, value);
        }
        public static Double GetAngle(UIElement element)
        {
            return (Double)element.GetValue(AngleProperty);
        }
        private static void OnAnglePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) {
            var child = sender as UIElement;
            ArrangeChild(child);
        }

        public static readonly DependencyProperty RadiusProperty = DependencyProperty.RegisterAttached(
          "Radius",
          typeof(Double),
          typeof(DirectRadialPanel),
          new PropertyMetadata(0.0, new PropertyChangedCallback(OnRadiusPropertyChanged))
        );
        public static void SetRadius(UIElement element, Double value)
        {
            element.SetValue(RadiusProperty, value);
        }
        public static Double GetRadius(UIElement element)
        {
            return (Double)element.GetValue(RadiusProperty);
        }
        private static void OnRadiusPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) {
            var child = sender as UIElement;
            ArrangeChild(child);
        }


        private static readonly DependencyProperty CenterProperty = DependencyProperty.RegisterAttached(
          "Center",
          typeof(Point),
          typeof(DirectRadialPanel),
          new PropertyMetadata(new Point(), null)
        );
        private static void SetCenter(UIElement element, Point value)
        {
            element.SetValue(CenterProperty, value);
        }
        private static Point GetCenter(UIElement element)
        {
            return (Point)element.GetValue(CenterProperty);
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            double maxChildRadius = 0;
            foreach (UIElement child in Children)
            {
                child.Measure(new
                    Size(Double.PositiveInfinity,
                         Double.PositiveInfinity));
                maxChildRadius =
                    Math.Max(maxChildRadius, GetRadius(child));
            }
            double squareSize = 2 * (maxChildRadius);
            return new Size(squareSize, squareSize);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            var centerX = finalSize.Width / 2;
            var centerY = finalSize.Height / 2;
            foreach (UIElement child in Children)
            {
                child.SetValue(CenterProperty, new Point(centerX, centerY));
                ArrangeChild(child);
            }

            return finalSize;
        }

        private static void ArrangeChild(UIElement child)
        {
            child.RenderTransform = new RotateTransform();
            RotateTransform rotateTransform =
                child.RenderTransform as RotateTransform;
            rotateTransform.Angle = GetAngle(child);
            rotateTransform.CenterX =
                child.DesiredSize.Width / 2;
            rotateTransform.CenterY = -GetRadius(child);
            child.Arrange(new Rect(
                new Point(GetCenter(child).X - child.DesiredSize.Width / 2,
                    GetCenter(child).Y + GetRadius(child)),
                new Size(child.DesiredSize.Width,
                         child.DesiredSize.Height)));
        }

    
    }
}
